home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 366_01 / ue311c1.arc / EVAL.C < prev    next >
C/C++ Source or Header  |  1991-10-30  |  35KB  |  1,382 lines

  1. /*    EVAL.C: Expresion evaluation functions for
  2.         MicroEMACS
  3.  
  4.     written 1986 by Daniel Lawrence             */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "eproto.h"
  9. #include    "edef.h"
  10. #include    "elang.h"
  11. #include    "evar.h"
  12.  
  13. PASCAL NEAR varinit()    /* initialize the user variable list */
  14.  
  15. {
  16.     register int i;
  17.  
  18.     for (i=0; i < MAXVARS; i++)
  19.         uv[i].u_name[0] = 0;
  20. }
  21.  
  22. PASCAL NEAR varclean()    /* initialize the user variable list */
  23.  
  24. {
  25.     register int i;
  26.  
  27.     for (i=0; i < MAXVARS; i++)
  28.         if (uv[i].u_name[0] != 0)
  29.             free(uv[i].u_value);
  30. }
  31.  
  32. char *PASCAL NEAR gtfun(fname)    /* evaluate a function */
  33.  
  34. char *fname;        /* name of function to evaluate */
  35.  
  36. {
  37.     register int fnum;        /* index to function to eval */
  38.     register int arg;        /* value of some arguments */
  39.     char arg1[NSTRING];        /* value of first argument */
  40.     char arg2[NSTRING];        /* value of second argument */
  41.     char arg3[NSTRING];        /* value of third argument */
  42.     static char result[2 * NSTRING];    /* string result */
  43. #if    ENVFUNC
  44.     char *getenv();         /* get environment string */
  45. #endif
  46.  
  47.     /* look the function up in the function table */
  48.     fname[3] = 0;    /* only first 3 chars significant */
  49.     mklower(fname); /* and let it be upper or lower case */
  50.     fnum = binary(fname, funval, NFUNCS);
  51.  
  52.     /* return errorm on a bad reference */
  53.     if (fnum == -1)
  54.         return(errorm);
  55.  
  56.     /* if needed, retrieve the first argument */
  57.     if (funcs[fnum].f_type >= MONAMIC) {
  58.         if (macarg(arg1) != TRUE)
  59.             return(errorm);
  60.  
  61.         /* if needed, retrieve the second argument */
  62.         if (funcs[fnum].f_type >= DYNAMIC) {
  63.             if (macarg(arg2) != TRUE)
  64.                 return(errorm);
  65.  
  66.             /* if needed, retrieve the third argument */
  67.             if (funcs[fnum].f_type >= TRINAMIC)
  68.                 if (macarg(arg3) != TRUE)
  69.                     return(errorm);
  70.         }
  71.     }
  72.  
  73.  
  74.     /* and now evaluate it! */
  75.     switch (fnum) {
  76.         case UFADD:    return(int_asc(asc_int(arg1) + asc_int(arg2)));
  77.         case UFSUB:    return(int_asc(asc_int(arg1) - asc_int(arg2)));
  78.         case UFTIMES:    return(int_asc(asc_int(arg1) * asc_int(arg2)));
  79.         case UFDIV:    return(int_asc(asc_int(arg1) / asc_int(arg2)));
  80.         case UFMOD:    return(int_asc(asc_int(arg1) % asc_int(arg2)));
  81.         case UFNEG:    return(int_asc(-asc_int(arg1)));
  82.         case UFCAT:    strcpy(result, arg1);
  83.                 return(strcat(result, arg2));
  84.         case UFLEFT:    return(bytecopy(result, arg1, asc_int(arg2)));
  85.         case UFRIGHT:    arg = asc_int(arg2);
  86.                 if (arg > strlen(arg1))
  87.                     arg = strlen(arg1);
  88.                 return(strcpy(result,
  89.                     &arg1[strlen(arg1) - arg]));
  90.         case UFMID:    arg = asc_int(arg2);
  91.                 if (arg > strlen(arg1))
  92.                     arg = strlen(arg1);
  93.                 return(bytecopy(result, &arg1[arg-1],
  94.                     asc_int(arg3)));
  95.         case UFNOT:    return(ltos(stol(arg1) == FALSE));
  96.         case UFEQUAL:    return(ltos(asc_int(arg1) == asc_int(arg2)));
  97.         case UFLESS:    return(ltos(asc_int(arg1) < asc_int(arg2)));
  98.         case UFGREATER: return(ltos(asc_int(arg1) > asc_int(arg2)));
  99.         case UFGROUP:
  100.                 if ((arg = asc_int(arg1)) < 0 || arg >= MAXGROUPS)
  101.                     return(bytecopy(result, errorm, NSTRING * 2));
  102.                     
  103. #if    MAGIC
  104.                 return(bytecopy(result, fixnull(grpmatch[arg]),
  105.                      NSTRING * 2));
  106. #else
  107.                 if (arg == 0)
  108.                     bytecopy(result, patmatch, NSTRING * 2);
  109.                 else
  110.                     result[0] = '\0';
  111.                 return(result);
  112. #endif
  113.         case UFSEQUAL:    return(ltos(strcmp(arg1, arg2) == 0));
  114.         case UFSLESS:    return(ltos(strcmp(arg1, arg2) < 0));
  115.         case UFSGREAT:    return(ltos(strcmp(arg1, arg2) > 0));
  116.         case UFIND:    return(strcpy(result, fixnull(getval(arg1))));
  117.         case UFAND:    return(ltos(stol(arg1) && stol(arg2)));
  118.         case UFOR:    return(ltos(stol(arg1) || stol(arg2)));
  119.         case UFLENGTH:    return(int_asc(strlen(arg1)));
  120.         case UFUPPER:    return(mkupper(arg1));
  121.         case UFLOWER:    return(mklower(arg1));
  122.         case UFTRUTH:    return(ltos(asc_int(arg1) == 42));
  123.         case UFASCII:    return(int_asc((int)arg1[0]));
  124.         case UFCHR:    result[0] = asc_int(arg1);
  125.                 result[1] = 0;
  126.                 return(result);
  127.         case UFGTCMD:    cmdstr(getcmd(), result);
  128.                 return(result);
  129.         case UFGTKEY:    result[0] = tgetc();
  130.                 result[1] = 0;
  131.                 return(result);
  132.         case UFRND:    return(int_asc((ernd() % absv(asc_int(arg1))) + 1));
  133.         case UFABS:    return(int_asc(absv(asc_int(arg1))));
  134.         case UFSINDEX:    return(int_asc(sindex(arg1, arg2)));
  135.         case UFENV:
  136. #if    ENVFUNC
  137.                 return(fixnull(getenv(arg1)));
  138. #else
  139.                 return("");
  140. #endif
  141.         case UFBIND:    return(transbind(arg1));
  142.         case UFEXIST:    return(ltos(fexist(arg1)));
  143.         case UFFIND:
  144.                 return(fixnull(flook(arg1, TRUE)));
  145.         case UFBAND:    return(int_asc(asc_int(arg1) & asc_int(arg2)));
  146.         case UFBOR:    return(int_asc(asc_int(arg1) | asc_int(arg2)));
  147.         case UFBXOR:    return(int_asc(asc_int(arg1) ^ asc_int(arg2)));
  148.         case UFBNOT:    return(int_asc(~asc_int(arg1)));
  149.         case UFXLATE:    return(xlat(arg1, arg2, arg3));
  150.         case UFTRIM:    return(trimstr(arg1));
  151.         case UFSLOWER:    return(setlower(arg1, arg2), "");
  152.         case UFSUPPER:    return(setupper(arg1, arg2), "");
  153.          case UFISNUM:    return(ltos(is_num(arg1)));
  154.     }
  155.  
  156.     meexit(-11);    /* never should get here */
  157. }
  158.  
  159. char *PASCAL NEAR gtusr(vname)    /* look up a user var's value */
  160.  
  161. char *vname;        /* name of user variable to fetch */
  162.  
  163. {
  164.     register int vnum;    /* ordinal number of user var */
  165.     register char *vptr;    /* temp pointer to function value */
  166.  
  167.     /* limit comparisons to significant length */
  168.     if (strlen(vname) >= NVSIZE)    /* "%" counts, but is not passed */
  169.         vname[NVSIZE-1] = '\0';
  170.  
  171.     /* scan the list looking for the user var name */
  172.     for (vnum = 0; vnum < MAXVARS; vnum++) {
  173.         if (uv[vnum].u_name[0] == 0)
  174.             return(errorm);
  175.         if (strcmp(vname, uv[vnum].u_name) == 0) {
  176.             vptr = uv[vnum].u_value;
  177.             if (vptr)
  178.                 return(vptr);
  179.             else
  180.                 return(errorm);
  181.         }
  182.     }
  183.  
  184.     /* return errorm if we run off the end */
  185.     return(errorm);
  186. }
  187.  
  188. char *PASCAL NEAR funval(i)
  189.  
  190. int i;
  191.  
  192. {
  193.     return(funcs[i].f_name);
  194. }
  195.  
  196. char *PASCAL NEAR envval(i)
  197.  
  198. int i;
  199.  
  200. {
  201.     return(envars[i]);
  202. }
  203.  
  204. PASCAL NEAR binary(key, tval, tlength)
  205.  
  206. char *key;        /* key string to look for */
  207. char *(PASCAL NEAR *tval)();    /* ptr to function to fetch table value with */
  208. int tlength;        /* length of table to search */
  209.  
  210. {
  211.     int l, u;    /* lower and upper limits of binary search */
  212.     int i;        /* current search index */
  213.     int cresult;    /* result of comparison */
  214.  
  215.     /* set current search limit as entire list */
  216.     l = 0;
  217.     u = tlength - 1;
  218.  
  219.     /* get the midpoint! */
  220.     while (u >= l) {
  221.         i = (l + u) >> 1;
  222.  
  223.         /* do the comparison */
  224.         cresult = strcmp(key, (*tval)(i));
  225.         if (cresult == 0)
  226.             return(i);
  227.         if (cresult < 0)
  228.             u = i - 1;
  229.         else
  230.             l = i + 1;
  231.     }
  232.     return(-1);
  233. }
  234.  
  235. char *PASCAL NEAR gtenv(vname)
  236.  
  237. char *vname;        /* name of environment variable to retrieve */
  238.  
  239. {
  240.     register int vnum;    /* ordinal number of var refrenced */
  241.     static char result[2 * NSTRING];    /* string result */
  242.  
  243.     /* scan the list, looking for the referenced name */
  244.     vnum = binary(vname, envval, NEVARS);
  245.  
  246.     /* return errorm on a bad reference */
  247.     if (vnum == -1)
  248.         return(errorm);
  249.  
  250.     /* otherwise, fetch the appropriate value */
  251.     switch (vnum) {
  252.         case EVFILLCOL: return(int_asc(fillcol));
  253.         case EVPAGELEN: return(int_asc(term.t_nrow + 1));
  254.         case EVCURCOL:    return(int_asc(getccol(FALSE)));
  255.         case EVCURLINE: return(int_asc(getlinenum(curbp, curwp->w_dotp)));
  256.         case EVRAM:    return(int_asc((int)(envram / 1024l)));
  257.         case EVFLICKER: return(ltos(flickcode));
  258.         case EVCURWIDTH:return(int_asc(term.t_ncol));
  259.         case EVCBFLAGS: return(int_asc(curbp->b_flag));
  260.         case EVCBUFNAME:return(curbp->b_bname);
  261.         case EVCFNAME:    return(curbp->b_fname);
  262.         case EVSRES:    return(sres);
  263.         case EVDEBUG:    return(ltos(macbug));
  264.         case EVSTATUS:    return(ltos(cmdstatus));
  265.         case EVPALETTE: return(palstr);
  266.         case EVASAVE:    return(int_asc(gasave));
  267.         case EVACOUNT:    return(int_asc(gacount));
  268.         case EVLASTKEY: return(int_asc(lastkey));
  269.         case EVCURCHAR:
  270.             return(curwp->w_dotp->l_used ==
  271.                     curwp->w_doto ? int_asc('\r') :
  272.                 int_asc(lgetc(curwp->w_dotp, curwp->w_doto)));
  273.         case EVDISCMD:    return(ltos(discmd));
  274.         case EVVERSION: return(VERSION);
  275.         case EVPROGNAME:return(PROGNAME);
  276.         case EVLANG:    return(LANGUAGE);
  277.         case EVSEED:    return(int_asc(seed));
  278.         case EVDISINP:    return(ltos(disinp));
  279.         case EVWLINE:    return(int_asc(cu